/**
 * LightCC API 服务层
 * 用于与 LightCC ComfyUI 服务进行通信
 */

import { notification } from '../components/Notification';

// API 配置
const LIGHTCC_API_BASE = '/api/lightcc'  // 使用代理路径
const API_KEY = '6948fec62ff649848bc0be21a49275f6'

// API 响应类型定义
interface ApiResponse<T = any> {
  code: number
  msg: string | null
  data: T
}

interface UploadPathResponse {
  fileName: string
  url: string
}

interface CreateTaskResponse {
  taskId: string
  status: number // 0: 排队
}

interface TaskProgressResponse {
  taskId: string
  status: number // 0: 排队；1: 运行；2: 中断；3: 异常；4：完成
  process: number // 任务进度百分比
  msg: string // 进度日志
}

interface TaskResultResponse {
  taskId: string
  status: number
  costPoint: number // 消耗算力点
  result: string[] // 执行结果图片地址
  error: string | null // 执行错误信息
  startTime: number // 开始时间
  endTime: number // 结束时间
}

interface RunningTaskInfo {
  taskId: string
  status: number
  costPoint?: number
  result?: string[]
  error?: string | null
  startTime?: number
  endTime?: number
  process?: number
  msg?: string
}

// 移除AllTasksResponse，直接使用RunningTaskInfo[]数组

export class LightCCApiService {
  private baseUrl: string
  private apiKey: string

  constructor() {
    this.baseUrl = LIGHTCC_API_BASE
    this.apiKey = API_KEY
  }

  /**
   * 获取请求头
   */
  private getHeaders(): HeadersInit {
    return {
      'X-Api-Key': this.apiKey,
      'Content-Type': 'application/json'
    }
  }

  /**
   * 处理API响应
   */
  private async handleResponse<T>(response: Response): Promise<ApiResponse<T>> {
    if (!response.ok) {
      if (response.status === 500) {
        notification.error('服务器内部错误，请稍后重试或联系技术支持', 5000);
        throw new Error(`服务器内部错误 (500): 请稍后重试或联系技术支持`)
      }
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    const data = await response.json()
    
    if (data.code !== 200) {
      // 特殊处理余额不足错误
      if (data.msg && data.msg.includes('余额不足')) {
        throw new Error(`余额不足: ${data.msg}。请充值后再试。`)
      }
      throw new Error(`API error: ${data.msg || 'Unknown error'}`)
    }
    
    return data
  }

  /**
   * 1. 获取上传预签名URL
   * @param fileType 文件类型，例如：png, jpg, jpeg
   */
  async getUploadPath(fileType: string): Promise<UploadPathResponse> {
    try {
      const response = await fetch(`${this.baseUrl}/task/minio/uploadPath/${fileType}`, {
        method: 'GET',
        headers: this.getHeaders()
      })

      const result = await this.handleResponse<UploadPathResponse>(response)
      return result.data
    } catch (error) {
      console.error('获取上传路径失败:', error)
      throw error
    }
  }

  /**
   * 2. 上传文件到预签名URL
   * @param file 要上传的文件
   * @param uploadUrl 预签名上传URL
   */
  async uploadFile(file: File, uploadUrl: string): Promise<void> {
    try {
      const response = await fetch(uploadUrl, {
        method: 'PUT',
        body: file,
        headers: {
          'Content-Type': file.type
        }
      })

      if (!response.ok) {
        throw new Error(`文件上传失败: ${response.status}`)
      }
    } catch (error) {
      console.error('文件上传失败:', error)
      throw error
    }
  }

  /**
   * 3. 创建ComfyUI任务
   * @param workflow ComfyUI工作流JSON
   * @param images 图片文件名数组
   * @param comfyApiKey ComfyUI API密钥
   */
  async createTask(workflow: any, images: string[] = [], comfyApiKey?: string): Promise<CreateTaskResponse> {
    try {
      const url = `${this.baseUrl}/task/create`
      const requestBody: any = {
        prompt: workflow,
        images: images
      }
      
      // 如果提供了comfyApiKey，添加到请求体中
      if (comfyApiKey) {
        requestBody.comfyApiKey = comfyApiKey
      }
      
      console.log('创建任务请求URL:', url)
      console.log('请求体:', requestBody)
      
      const response = await fetch(url, {
        method: 'POST',
        headers: this.getHeaders(),
        body: JSON.stringify(requestBody)
      })
      
      console.log('响应状态:', response.status)
      console.log('响应头:', Object.fromEntries(response.headers.entries()))

      const result = await this.handleResponse<CreateTaskResponse>(response)
      return result.data
    } catch (error) {
      console.error('创建任务失败:', error)
      throw error
    }
  }

  /**
   * 4. 获取任务执行日志和进度
   * @param taskId 任务ID
   */
  async getTaskProgress(taskId: string): Promise<TaskProgressResponse> {
    try {
      const response = await fetch(`${this.baseUrl}/task/processLog/${taskId}`, {
        method: 'GET',
        headers: this.getHeaders()
      })

      const result = await this.handleResponse<TaskProgressResponse>(response)
      return result.data
    } catch (error) {
      console.error('获取任务进度失败:', error)
      // 这里不需要额外的 notification，因为 handleResponse 已经处理了
      throw error
    }
  }

  /**
   * 5. 获取任务执行结果
   * @param taskId 任务ID
   */
  async getTaskResult(taskId: string): Promise<TaskResultResponse> {
    try {
      console.log('获取任务结果，任务ID:', taskId);
      const response = await fetch(`${this.baseUrl}/task/result/${taskId}`, {
        method: 'GET',
        headers: this.getHeaders()
      })

      const result = await this.handleResponse<TaskResultResponse>(response)
      console.log('任务结果响应:', result);
      return result.data
    } catch (error) {
      console.error('获取任务结果失败:', error)
      throw error
    }
  }

  /**
   * 7. 获取所有运行中的任务
   * @returns 运行中的任务列表
   */
  async getAllRunningTasks(): Promise<RunningTaskInfo[]> {
    try {
      console.log('获取所有运行中的任务');
      const response = await fetch(`${this.baseUrl}/task/result`, {
        method: 'GET',
        headers: this.getHeaders()
      })

      const result = await this.handleResponse<RunningTaskInfo[]>(response)
      console.log('所有任务响应:', result);
      
      // 过滤出正在运行的任务 (status === 1)
      const runningTasks = result.data.filter(task => task.status === 1);
      console.log('运行中的任务:', runningTasks);
      
      return runningTasks
    } catch (error) {
      console.error('获取运行中任务失败:', error)
      throw error
    }
  }

  /**
   * 6. 中断任务
   * @param taskId 任务ID
   */
  async interruptTask(taskId: string): Promise<TaskResultResponse> {
    try {
      const response = await fetch(`${this.baseUrl}/task/interrupt/${taskId}`, {
        method: 'PUT',
        headers: this.getHeaders()
      })

      const result = await this.handleResponse<TaskResultResponse>(response)
      return result.data
    } catch (error) {
      console.error('中断任务失败:', error)
      throw error
    }
  }

  /**
   * 7. 检查账户余额（通过创建任务时的错误信息判断）
   */
  async checkBalance(): Promise<{ hasBalance: boolean; message: string }> {
    return { 
      hasBalance: true, 
      message: '无法直接检查余额，请在创建任务时查看错误信息' 
    }
  }

  /**
   * 7. 完整的图片上传流程
   * @param file 要上传的图片文件
   * @returns 返回包含 fileName 和 url 的对象
   */
  async uploadImage(file: File): Promise<{ fileName: string; url: string }> {
    try {
      // 获取文件扩展名
      const fileType = file.name.split('.').pop()?.toLowerCase()
      if (!fileType) {
        throw new Error('无法识别文件类型')
      }

      // 检查文件类型
      const allowedTypes = ['png', 'jpg', 'jpeg']
      if (!allowedTypes.includes(fileType)) {
        throw new Error('只支持 PNG、JPG、JPEG 格式的图片')
      }

      // 检查文件大小 (10MB)
      const maxSize = 10 * 1024 * 1024
      if (file.size > maxSize) {
        throw new Error('文件大小不能超过 10MB')
      }

      // 获取上传预签名URL
      const uploadPath = await this.getUploadPath(fileType)
      
      // 上传文件
      await this.uploadFile(file, uploadPath.url)
      
      return {
        fileName: uploadPath.fileName,
        url: uploadPath.url
      }
    } catch (error) {
      console.error('图片上传失败:', error)
      throw error
    }
  }

  /**
   * 8. 轮询任务进度直到完成
   * @param taskId 任务ID
   * @param onProgress 进度回调函数
   * @param maxAttempts 最大轮询次数，默认300次（5分钟）
   */
  async pollTaskProgress(
    taskId: string, 
    onProgress: (progress: TaskProgressResponse) => void,
    maxAttempts: number = 300
  ): Promise<TaskResultResponse> {
    let attempts = 0
    
    return new Promise((resolve, reject) => {
      const poll = async () => {
        try {
          attempts++
          const progress = await this.getTaskProgress(taskId)
          
          // 调用进度回调
          onProgress(progress)
          
          // 检查任务状态
          if (progress.status === 4) {
            // 任务完成，获取结果
            const result = await this.getTaskResult(taskId)
            resolve(result)
            return
          }
          
          if (progress.status === 2 || progress.status === 3) {
            // 任务中断或异常
            reject(new Error(`任务失败: ${progress.msg}`))
            return
          }
          
          if (attempts >= maxAttempts) {
            // 超时
            reject(new Error('任务超时'))
            return
          }
          
          // 继续轮询
          setTimeout(poll, 3000) // 3秒后再次检查
        } catch (error) {
          console.error('轮询任务进度时发生错误:', error)
          // 如果是服务器错误（500），直接停止轮询并抛出错误
          if (error instanceof Error && (error.message.includes('500') || error.message.includes('服务器内部错误'))) {
            notification.error('服务器内部错误，任务已停止', 5000);
            reject(new Error('服务器内部错误，请稍后重试'))
            return
          }
          
          // 如果是网络错误，尝试重试几次
          if (attempts < 3) {
            console.log(`网络错误，第 ${attempts} 次重试...`)
            notification.warning(`网络连接异常，正在重试... (${attempts}/3)`, 2000);
            setTimeout(poll, 2000) // 2秒后重试
            return
          }
          
          // 超过重试次数，显示最终错误
          notification.error('网络连接失败，请检查网络后重试', 5000);
          reject(error)
        }
      }
      
      poll()
    })
  }
}

// 创建单例实例
export const lightCCApi = new LightCCApiService()

// 导出工作流相关 API
export { workflowApi } from './workflowApi'
export { workflowManager } from './workflowManager'
export * from './workflowApis'

// 导出类型
export type {
  ApiResponse,
  UploadPathResponse,
  CreateTaskResponse,
  TaskProgressResponse,
  TaskResultResponse
}
